/*
 * Copyright (C) 2011. JiangHongTiao <jjurco.sk_gmail.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package sk.lieskove.jianghongtiao.websearch.document.preprocessing;

import org.apache.log4j.Logger;
import sk.lieskove.jianghongtiao.websearch.document.preprocessing.actions.*;
import sk.lieskove.jianghongtiao.websearch.service.ExcludeReasonEnum;
import sk.lieskove.jianghongtiao.websearch.persistence.WebSearchResponse;

import java.util.regex.Pattern;

/**
 * Created by: xjuraj
 * Date: 10/11/11
 * Time: 1:33 PM
 */
public class PreprocessorManager {

    private Logger log = Logger.getLogger(PreprocessorManager.class);
    private Pattern universalPattern = Pattern.compile(".*");
    private Pattern aresPattern = Pattern.compile(".*mfcr\\.cz.*");

    public WebSearchResponse preprocess(WebSearchResponse document) {
        WebSearchResponse result = document;
        SupportedMimeTypes mt = SupportedMimeTypes.fromValue(document.getMimeType());
        if (mt == SupportedMimeTypes.not_supported) {
            document.setExcludeReasonEnum(ExcludeReasonEnum.MIME_TYPE_NOT_SUPPORTED);
            return document;
        }

        // for universal URL pattern: ".*"
        switch (mt) {
            // PDF,PS
            case application_pdf:
            case application_postscript:
            case application_x_dvi:
                result = applyTransformChain(result,
                        new Pdf2Txt());
                break;
            // HTML
            case application_xhtml_xml:
            case text_html:
                result = applyTransformChain(result,
                        new RemoveIFrame());
            // XML
            case application_atom_xml:
            case application_rss_xml:
            case text_xml:
                // for ARES pattern: .*mfcr\\.cz.*
                if (aresPattern.matcher(document.getUrl()).matches()) {
                    result = applyTransformChain(result,
                            new AresExcludeNotFound(),
                            new Xml2txt()
//                            ,new Txt2Word()
                            );
                } else if (universalPattern.matcher(document.getUrl()).matches()) {
                    result = applyTransformChain(result,
                            new Enc2Utf8(),
                            new HtmlClean(),
                            new Html2Txt());
                } else {
                    throw new TypeNotPresentException(mt.value(), null);
                }
                break;
            // PLAIN TEXT
            case text_cmd:
            case text_csv:
            case text_plain:
                result = applyTransformChain(result,
                        new Enc2Utf8());
                break;
            // RTF Document
            case application_rtf:
            case text_rtf:
                result = applyTransformChain(result,
                        new Rtf2TxtExtract());
            // Open Document format       
            case application_vnd_oasis_opendocument_chart:
            case application_vnd_oasis_opendocument_chart_template:
            case application_vnd_oasis_opendocument_database:
            case application_vnd_oasis_opendocument_formula:
            case application_vnd_oasis_opendocument_formula_template:
            case application_vnd_oasis_opendocument_graphics:
            case application_vnd_oasis_opendocument_graphics_template:
            case application_vnd_oasis_opendocument_image:
            case application_vnd_oasis_opendocument_image_template:
            case application_vnd_oasis_opendocument_presentation:
            case application_vnd_oasis_opendocument_presentation_template:
            case application_vnd_oasis_opendocument_spreadsheet:
            case application_vnd_oasis_opendocument_spreadsheet_template:
            case application_vnd_oasis_opendocument_text:
            case application_vnd_oasis_opendocument_text_master:
            case application_vnd_oasis_opendocument_text_template:
            case application_vnd_oasis_opendocument_text_web:
                result = applyTransformChain(result,
                        new OpenDocument2Txt());
            // MS OFFICE formats - mess of the mime types
            case application_msword:
            case application_vnd_ms_word:
            case application_vnd_openxmlformats_officedocument_wordprocessingml_document:
            case application_vnd_openxmlformats_officedocument_wordprocessingml_template:
            case application_vnd_ms_word_document_macroEnabled_12:
            case application_vnd_ms_word_template_macroEnabled_12:
            case application_vnd_ms_excel:
            case application_vnd_openxmlformats_officedocument_spreadsheetml_sheet:
            case application_vnd_openxmlformats_officedocument_spreadsheetml_template:
            case application_vnd_ms_excel_sheet_macroEnabled_12:
            case application_vnd_ms_excel_template_macroEnabled_12:
            case application_vnd_ms_excel_addin_macroEnabled_12:
            case application_vnd_ms_excel_sheet_binary_macroEnabled_12:
            case application_vnd_ms_powerpoint:
            case application_vnd_openxmlformats_officedocument_presentationml_presentation:
            case application_vnd_openxmlformats_officedocument_presentationml_template:
            case application_vnd_openxmlformats_officedocument_presentationml_slideshow:
            case application_vnd_ms_powerpoint_addin_macroEnabled_12:
            case application_vnd_ms_powerpoint_presentation_macroEnabled_12:
            case application_vnd_ms_powerpoint_template_macroEnabled_12:
            case application_vnd_ms_powerpoint_slideshow_macroEnabled_12:
            case application_visio:
            case application_x_visio:
            case application_vnd_visio:
            case application_visio_drawing:
            case application_vsd:
            case application_x_vsd:
            case application_vnd_ms_outlook:
            case application_x_mspublisher:
            case application_vnd_ms_publisher:
            case image_x_vsd:
            case message_rfc822:
                result = applyTransformChain(result,
                        new PoiTextExtractor());
                break;
            // Shockwave Flash
            case application_x_shockwave_flash:
                result = applyTransformChain(result,
                        new FlashTextExtract());
                break;
        }
        result = applyTransformChain(result,
                new LangRecognition(),
//                new Txt2Word(),
//                new RemoveStopWords(),
                new CleanText(
                CleanTextActionsEnum.TO_LOWER,
                CleanTextActionsEnum.DECODE_HTML_ENTITIES,
                CleanTextActionsEnum.REGEXP_REPLACE,
                CleanTextActionsEnum.STRINGS_FOR_SPACE,
                CleanTextActionsEnum.CHARACTERS_FOR_SPACE,
                CleanTextActionsEnum.REMOVE_TRAILING_SPACES), 
                new ExcludeWithoutSearchQuery());
        return result;
    }

    private WebSearchResponse applyTransformChain(WebSearchResponse document,
            PreprocessAction... actions) {
        WebSearchResponse preprocess = document;
        for (PreprocessAction preprocessAction : actions) {
            if (preprocess.isAdequateDocument()) {
                preprocess = preprocessAction.preprocess(preprocess);
            } else {
                break;
            }
        }
        return preprocess;
    }
}
